package newapp.dob.com.dc_new_app.util;

import android.content.Context;
import android.text.TextUtils;
import android.widget.Toast;


import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import newapp.dob.com.dc_new_app.api.ResponseModel;
import newapp.dob.com.dc_new_app.base.BaseActivity;
import newapp.dob.com.dc_new_app.fragment.BaseFragment;

/**
 * Created by Administrator on 2017/3/2 0002.
 */

public class RxLifeUtil {
    public static <T extends ResponseModel> ObservableTransformer<T, T> checkOn(Context context) {
//        if (!(context instanceof BaseActivity)) {
//            throw SystemException.wrap(new Exception("API.checkOn : api request need BaseActivity context!"));
//        }
        if ((context instanceof BaseActivity)) {
            BaseActivity activity = (BaseActivity) context;
            return observable -> observable
                    .compose(activity.bindToLifecycle())
                    .compose(_checkOn(activity));
        } else {
            throw SystemException.wrap(new Exception("API.checkOn : api request need BaseActivity context!"));
        }
    }

    public static <T extends ResponseModel> ObservableTransformer<T, T> NocheckOn(Context context) {
        if (context instanceof BaseActivity) {
            BaseActivity activity = (BaseActivity) context;
            return observable -> observable
                    .compose(activity.bindToLifecycle())
                    .compose(_NocheckOn(activity));
        } else {
            throw SystemException.wrap(new Exception("API.checkOn : api request need BaseActivity context!"));
        }

    }

    public static <T extends ResponseModel> ObservableTransformer<T, T> NoErrorOn(Context context) {
        if (context instanceof BaseActivity) {
            BaseActivity activity = (BaseActivity) context;
            return observable -> observable
                    .compose(activity.bindToLifecycle())
                    .compose(_NoErrorcheckOn(activity));
        } else {
            throw SystemException.wrap(new Exception("API.checkOn : api request need BaseActivity context!"));
        }

    }

    public static <T extends ResponseModel> ObservableTransformer<T, T> checkOn(BaseFragment fragment) {
        return observable -> observable
                .compose(fragment.bindToLifecycle())
                .compose(_checkOn(fragment.getActivity()));
    }

    private static <T extends ResponseModel> ObservableTransformer<T, T> _checkOn(Context context) {
        return observable -> observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
//                .flatMap(refresh -> {
//                    if (refresh.status == 1001) {
//                        return Observable.error(new TimeOutException());
//                    }
//                    return Observable.just(refresh);
//                })
//                .retryWhen(new TimeOutRetry(context))
                .filter(result -> _check(context, result))
                .doOnError(throwable -> {
                    ExceptionEngine.handleException(context, throwable);
//                    Toast.makeText(context, "服务器发生了错误", Toast.LENGTH_SHORT).show();
                })
                .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends T>>() {
                    @Override
                    public ObservableSource<? extends T> apply(Throwable throwable) throws Exception {
                        throwable.printStackTrace();
                        return Observable.empty();
                    }
                });

    }

    private static <T extends ResponseModel> ObservableTransformer<T, T> _NoErrorcheckOn(Context context) {
        return observable -> observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread());
//                .flatMap(refresh -> {
//                    if (refresh.status == 1001) {
//                        return Observable.error(new TimeOutException());
//                    }
//                    return Observable.just(refresh);
//                })
//                .retryWhen(new TimeOutRetry(context))

    }

    private static <T extends ResponseModel> ObservableTransformer<T, T> _NocheckOn(Context context) {
        return observable -> observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
//                .flatMap(refresh -> {
//                    if (refresh.status == 1001) {
//                        return Observable.error(new TimeOutException());
//                    }
//                    return Observable.just(refresh);
//                })
//                .retryWhen(new TimeOutRetry(context))
                .doOnError(throwable -> {
                    ExceptionEngine.handleException(context, throwable);
                })
                .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends T>>() {
                    @Override
                    public ObservableSource<? extends T> apply(Throwable throwable) throws Exception {
                        throwable.printStackTrace();
                        return Observable.empty();
                    }
                });

    }

    private static boolean _check(Context context, ResponseModel ResponseModel) {
        if (ResponseModel.getStatus().equals("000")) {
            return true;
        }
        if (!TextUtils.isEmpty(ResponseModel.getMsg())) {
            Toast.makeText(context, ResponseModel.getMsg(), Toast.LENGTH_SHORT).show();
        }
        return false;
    }

    private static <T> Observable<T> _catch(Throwable throwable) {
        throwable.printStackTrace();
        return Observable.empty();
    }

    private static class TimeOutException extends Exception {
    }

    private static class TimeOutRetry implements Function<Observable<? extends Throwable>, Observable<?>> {
        public Context context;

        public TimeOutRetry(Context context) {
            this.context = context;
        }

        @Override
        public Observable<?> apply(Observable<? extends Throwable> observable) throws Exception {
            return observable.flatMap(new Function<Throwable, ObservableSource<?>>() {
                @Override
                public ObservableSource<?> apply(Throwable throwable) throws Exception {
                    if (throwable instanceof TimeOutException) {

//                        return KuaiJieApi.instance.refreshToken()
//                                .subscribeOn(Schedulers.io())
//                                .observeOn(AndroidSchedulers.mainThread())
//                                .unsubscribeOn(Schedulers.io())
//                                .filter(result -> {
//                                    if (result.status != 0) {
//                                        UI.showToast(context, "认证失败，请重新登录");
//
//                                        return false;
//                                    } else {
//                                        return true;
//                                    }
//                                })
//                                .doOnNext(new Action1<TotalRefreshToken>() {
//                                    @Override
//                                    public void call(TotalRefreshToken result) {
//                                        Global.refreshToken(result.result.access_token);
//                                    }
//                                });
//                                            AppApplication.getInstance().getAppComponent().getReaderApi()
                    }
                    return null;
                }
            });
        }
    }
}


